package com.wn.main.ui.home.repository

import android.content.Context
import com.wn.common.constant.FILE_VIDEO_LIST
import com.wn.common.db.dao.VideoListCacheDao
import com.wn.common.db.entity.VideoInfo
import com.wn.common.model.Banner
import com.wn.common.model.ProjectTabItem
import com.wn.common.model.SubProjectList
import com.wn.common.utils.ParseFileUtils
import com.wn.network.api.ApiInterface
import com.wn.network.flow.getStateFlowLocal
import com.wn.network.repository.BaseRepository
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.android.scopes.ViewModelScoped
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.StateFlow
import javax.inject.Inject

/**
 * @Author: wn
 * @Date: 2024/9/26 17:16
 * @Description: 首页仓库
 */
@ViewModelScoped
class HomeRepository @Inject constructor(
  @ApplicationContext private val context: Context,
  private val api: ApiInterface,
  private val videoListCacheDao: VideoListCacheDao,
) : BaseRepository() {
  /**
   * 获取首页轮播图
   */
  val getHomeBanner: (
    scope: CoroutineScope,
    errorCall: ((Int?, String?) -> Unit)?,
    showLoading: ((Boolean) -> Unit)?,
  ) -> StateFlow<MutableList<Banner>?> = { scope, errorCall, showLoading ->
    callStateFlow(scope, errorCall, showLoading) {
      api.getHomeBanner()
    }
  }

  /**
   * 获取首页 TabLayout 数据
   */
  val getHomeTabs: (
    scope: CoroutineScope,
    errorCall: ((Int?, String?) -> Unit)?,
    showLoading: ((Boolean) -> Unit)?,
  ) -> StateFlow<MutableList<ProjectTabItem>?> = { scope, errorCall, showLoading ->
    callStateFlow(scope, errorCall, showLoading) {
      api.getProjectTab()
    }
  }

  /**
   * 获取首页 视频列表
   * 先从数据库读取 没有在 网络获取
   * 读取 assets目录下的文件
   * 直接 FlowFun 不经过 BaseRepository
   */
  val getVideoList: (
    scope: CoroutineScope,
    errorCall: ((Int?, String?) -> Unit)?,
    showLoading: ((Boolean) -> Unit)?,
  ) -> StateFlow<MutableList<VideoInfo>?> = { scope, errorCall, showLoading ->
    getStateFlowLocal(scope, errorCall, showLoading) {
      var list = getVideoListByDB()
      if (list.isNullOrEmpty()) {
        list = ParseFileUtils.parseAssetsFile(context.assets, FILE_VIDEO_LIST)
        insertVideoListByDB(list)
      }
      list
    }
  }

  /**
   * 数据库 读取 数据 返回 Flow<List>
   * @return Flow<MutableList<VideoInfo>?>
   */
  private fun getVideoListByDB() = videoListCacheDao.queryAll()

  private suspend fun insertVideoListByDB(videoList: MutableList<VideoInfo>) =
    videoListCacheDao.insertAll(videoList)

  /**
   * 获取项目列表数据
   * @param page Int                                         -- 页码
   * @param cid Int                                          -- id
   * @param scope CoroutineScope                             -- 协程作用域
   * @param errorCall Function2<Int?, String?, Unit>?        -- 错误参数
   * @param showLoading Function1<Boolean, Unit>?            -- 是否加载
   * @return StateFlow<SubProjectList?>                      -- StateFlow
   */
  fun getProjectList(
    page: Int,
    cid: Int,
    scope: CoroutineScope,
    errorCall: ((Int?, String?) -> Unit)? = null,
    showLoading: ((Boolean) -> Unit)? = null,
  ): StateFlow<SubProjectList?> = callStateFlow(scope, errorCall, showLoading) {
    api.getSubProjectList(page, cid)
  }
}